package cn.itcast.web.controller.system;

import cn.itcast.domain.system.Module;
import cn.itcast.domain.system.Role;
import cn.itcast.service.system.ModuleService;
import cn.itcast.service.system.RoleService;
import cn.itcast.web.controller.BaseController;
import cn.itcast.web.utils.JedisUtils;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.github.pagehelper.PageInfo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import redis.clients.jedis.Jedis;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Controller
@RequestMapping("/system/role")
@Slf4j
public class RoleController extends BaseController {

    @Autowired
    private RoleService roleService;

    /**
     * 列表
     * @param pageNum  当前页，默认1
     * @param pageSize 页大小，默认5
     * @return 返回页面路径（前缀后缀在视图解析器中配置）
     */
    @RequestMapping("/list")
    public String list(@RequestParam(defaultValue = "1") Integer pageNum,
                       @RequestParam(defaultValue = "5") Integer pageSize) {
        log.info("执行查询角色列表:");

        // 根据登陆用户的企业id查询用户，目前先写死
        String companyId = getLoginCompanyId();
        PageInfo<Role> pageInfo = roleService.findByPage(companyId, pageNum, pageSize);
        request.setAttribute("pageInfo", pageInfo);
        return "system/role/role-list";
    }

    /**
     * 进入添加页面
     */
    @RequestMapping("/toAdd")
    public String toAdd() {
        return "system/role/role-add";
    }

    /**
     * 添加或修改
     */
    @RequestMapping("/edit")
    public String edit(Role role) {

        // 设置企业信息（从登陆用户中获取）
        role.setCompanyId(getLoginCompanyId());
        role.setCompanyName(getLoginCompanyName());

        // 判断：根据id是否为空判断执行添加还是修改
        if (StringUtils.isEmpty(role.getId())) {

            // 添加
            roleService.save(role);
        } else {
            // 修改
            roleService.update(role);
        }

        return "redirect:/system/role/list";
    }

    /**
     * 进入修改页面
     */
    @RequestMapping("/toUpdate")
    public String toUpdate(String id, Model model) {
        // 根据id查询
        Role role = roleService.findById(id);
        model.addAttribute("role", role);
        return "system/role/role-update";
    }

    /**
     * 删除
     */
    @RequestMapping("/delete")
    public String delete(String id) {
        roleService.delete(id);
        return "redirect:/system/role/list";
    }

    /**
     * 角色分配权限（1）从role-list.jsp点击权限，进入到角色分配权限页面role-module.jsp
     */
    @RequestMapping("/roleModule")
    public String roleModule(String roleId) {
        // 根据角色id，查询角色信息
        Role role = roleService.findById(roleId);
        request.setAttribute("role",role);
        return "system/role/role-module";
    }

    @Autowired
    private ModuleService moduleService;

    /**
     * 角色分配权限（2）role-module.jsp发送异步请求，返回ztree需要的json格式数据
     * 返回数据：
     *   result = [
     *      { id:2, pId:0, name:"随意勾选 2", checked:true, open:true}
     *   ]
     */
    @RequestMapping("/getZtreeNodes")
    @ResponseBody
    public List<Map<String,Object>> getZtreeNodes(String roleId) throws Exception {
        //添加jedis集合
        List<Module> moduleList;
        List<Module> roleModuleList;
        ObjectMapper mapper = new ObjectMapper();
        //1. 定义方法返回的对象
        List<Map<String,Object>> result = new ArrayList<>();
        //通过工具类连接redis
        Jedis jedis = JedisUtils.getJedis();


        //先从redis中查询所有权限
        String moduleListString = jedis.get("moduleList");
        if(moduleListString==null){//在ridis中未查找到数据,走数库查询
            moduleList = moduleService.findAll();
            //查询到数据后将数据同步到redis中
            log.info("从数据库中获取所有权限");
            String jsonMuduleList = mapper.writeValueAsString(moduleList);
            jedis.set("moduleList",jsonMuduleList);
        }else {
            log.info("从redis中获取所有权限");
            //在redis中查找到数据,直接从redis中获取
            moduleList = mapper.readValue(moduleListString,new TypeReference<List<Module>>(){});
        }

        //查询当前角色拥有的权限
        //List<Module> roleModuleList = moduleService.findModuleByRoleId(roleId);
        String roleModuleListString = jedis.get("roleModuleList"+roleId);
        if(roleModuleListString==null){
            log.info("从数据库中查询角色权限");
            roleModuleList = moduleService.findModuleByRoleId(roleId);
            //将查询到的用户所属权限存入redis中
            String jsonRoleModuleList = mapper.writeValueAsString(roleModuleList);
            jedis.set("roleModuleList"+roleId,jsonRoleModuleList);
        }else {
            log.info("从redis中获取用户所属权限");
             roleModuleList  = mapper.readValue(roleModuleListString, new TypeReference<List<Module>>() {
            });
        }
        //4. 封装返回结果
        for (Module module : moduleList) {
            //4.1 定义map，封装json数据
            Map<String,Object> map = new HashMap<>();
            map.put("id",module.getId());
            map.put("pId",module.getParentId());
            map.put("name",module.getName());
            map.put("open",true);
            //4.2 设置选中 (如果当前角色拥有的权限包含遍历的权限，则选中)
            if (roleModuleList.contains(module)){
                map.put("checked",true);
            }
            //4.3 map添加到list集合
            result.add(map);
        }

        return result;
    }


    /**
     * 角色分配权限（3）role-module.jsp点击保存，最终实现角色分配权限
     * @param roleId    角色id
     * @param moduleIds 权限id，多个权限id用逗号隔开
     * @return
     */
    @RequestMapping("/updateRoleModule")
    public String updateRoleModule(String roleId,String moduleIds) {
        //删除redis中的用户所属权限
        Jedis jedis = JedisUtils.getJedis();
        jedis.del("roleModuleList"+roleId);
        moduleService.updateRoleModule(roleId,moduleIds);
        return "redirect:/system/role/list";
    }
}